# -*- coding: utf-8 -*-

from osv import fields,osv
from osv.orm import browse_record
import tools
from functools import partial
import pytz
import pooler
from tools.translate import _
from service import security
import netsvc
import logging

class aas_user(osv.osv):
    logging.getLoggerClass()
    def get_country_id(self, cr, uid, code='VN', context=None):
        country_obj = self.pool.get('res.country')
        country_id = False
        countries_ids = country_obj.search(cr, uid, [('code', '=', code)], context=context)
        if len(countries_ids):
            country_id = countries_ids[0]
        return country_id
    
    def _country_id(self, cr, uid, context=None):
        return self.get_country_id(cr, uid, code='VN', context=context)
    
    def _disable_basic_info(self, cr, uid, ids, field_name, arg, context=None):
        result = {}
        for user in self.browse(cr, uid, ids, context=context):
            disable = True
            if uid == 1:
                disable = False
            result[user.id] = disable
        return result
    
    def _hide_more_info(self, cr, uid, ids, field_name, arg, context=None):
        result = {}
        for user in self.browse(cr, uid, ids, context=context):
            hide = True
            if uid == 1:
                hide = False
            if user.show_more_info == True:
                hide = False
            result[user.id] = hide
        return result
    
    def _hide_tab_config(self, cr, uid, ids, field_name, arg, context=None):
        result = {}
        for user in self.browse(cr, uid, ids, context=context):
            hide = True
            if user.id == uid or uid == 1:
                hide = False
            result[user.id] = hide
        return result
    
    def default_student(self, cr, uid, context=False):
        if not context: context = {}
        res = False
        res = context.get('student', False)
        return res
    
    def default_lecturer(self, cr, uid, context=False):
        if not context: context = {}
        res = False
        res = context.get('lecturer', False)
        return res
    
    def store_gpa(self, cr, uid, ids, context=False):
        res = []
        for obj in self.browse(cr, uid, ids, context=context):
            res.append(obj.student_id.id)
        return res 
    
    def function_gpa(self, cr, uid, ids, fields, args, context=False):
        res = {}
        for obj in self.browse(cr, uid, ids, context=context):
            gpa = 0.00
            study_results = self.get_study_result(cr, uid, obj.id, context=context)
            gpa = study_results.get('gpa', 0.00)
            res[obj.id] = gpa
        return res
                                        
    _inherit = 'res.users'
    _columns = {
        'code': fields.char('Mã số', size=64, required=True),
        'name_last': fields.char('Họ và tên đệm', size=64, required=True),
        'name_first': fields.char('Tên', size=64, required=True),
        'name': fields.char('Họ tên đầy đủ', size=64, required=True),
        'gender': fields.selection((('male', _('Nam')), ('female', _('Nữ'))), string="Giới tính", required=True),
        'date_birth': fields.date('Ngày sinh', required=False),
        'place_birth': fields.char('Nơi sinh', size=64, required=False),
        'mother_name': fields.char('Họ tên mẹ', size=128, required=False),
        'father_name': fields.char('Họ tên cha', size=128, required=False),
        'gov_id': fields.char('Số CMND', size=64, required=False),
        'gov_id_date': fields.date('Ngày cấp', required=False),
        'gov_id_place': fields.char('Nơi cấp', size=64, required=False),
        'cur_addr': fields.char('Địa chỉ hiện tại', size=128,),
        'perm_addr': fields.char('Hộ khẩu thường trú', size=128,),
        'tel': fields.char('Số điện thoại cố định', size=64,),
        'mobile': fields.char('Số điện thoại di động', size=64,),
        'email': fields.char('Địa chỉ email', size=64,),
        'fax': fields.char('Số fax', size=64,),
        'tax_code': fields.char('Mã số thuế', size=64,),
        'country_id': fields.many2one('res.country', string='Quốc gia'),
        'date_entrance': fields.date('Date of Entrance',),
        #'class_entrance': fields.date('Class of Entrance',),
#        'academic_degree_id': fields.many2one('aas.academic.degree', string='Academic Degree'),
#        'academic_type_id': fields.many2one('aas.academic.type', string='Academic Type'),
        'receive_emails': fields.boolean('Nhận emails khi có thông báo mới'),
        'semester_entrance': fields.many2one('aas.academic.semester', string='Semester Entrance'),
        'year_entrance': fields.many2one('aas.academic.year', string='Year Entrance'),
        
        'show_more_info': fields.boolean('Hiển thị các thông tin khác'),
        'disable_basic_info': fields.function(_disable_basic_info, method=True, type='boolean', string=' '),
        'hide_more_info': fields.function(_hide_more_info, method=True, type='boolean', string=' '),
        'hide_tab_config': fields.function(_hide_tab_config, method=True, type='boolean', string=' '),
        'student': fields.boolean('Là sinh viên?'),
        'lecturer': fields.boolean('Là giảng viên?'),
#        'gpa': fields.function(function_gpa, method=True, type='float', string='GPA', digits=(16,2),
#                               store={'aas.course.student': (store_gpa, ['course_id',], 10)}),
    }
    _defaults = {
        'gender': lambda *a: 'male',
        'receive_emails': lambda *a: True,
        'show_more_info': lambda *a: False,
        'country_id': _country_id,
        'student': default_student,
        'lecturer': default_lecturer,
    }
    _sql_constraints = [
#        ('code_uniq', 'UNIQUE(code)', 'The code of a user must be unique!'),
    ]
    
    def create(self, cr, uid, vals, context=None):
        if not vals:
            vals = {}
        if vals.has_key('code'):
            vals['login'] = vals['code']
        if vals.has_key('name_first') or vals.has_key('name_last'):
            onchange_name_vals = self.onchange_name(cr, uid, [], vals.get('name_first', ''), vals.get('name_last', ''))['value']
            vals.update(onchange_name_vals)
        return super(aas_user, self).create(cr, uid, vals, context=context)
    
    def copy(self, cr, uid, id, default=None, context=None):
        if not default:
            default = {}
        user = self.browse(cr, uid, id, context=context)
        default.update({
            'code': (user.code or '') + ' (copied)',
        })
        return super(aas_user, self).copy(cr, uid, id, default, context)
    
    def write(self, cr, uid, ids, vals, context=None):
        return super(aas_user, self).write(cr, uid, ids, vals, context=context)
    
    def onchange_name(self, cr, uid, ids, name_first, name_last):
        result = {'value': {}}
        name = ''
        if name_last:
            name += name_last
        if name_first:
            if name: name += ' ' + name_first
            else: name += name_first
        result['value']['name'] = name
        return result
    
    def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
        if not args:
            args = []
        if not context:
            context = {}
        return super(aas_user, self).search(cr, uid, args, limit=limit, order=order, context=context, count=count)
    
    def name_search(self, cr, uid, name='', args=None, operator='ilike', context=None, limit=100):
        if not args:
            args = []
        if name:
            ids = self.search(cr, uid, [('code', operator, name)] + args, limit=limit, context=context)
            ids += self.search(cr, uid, [('name', operator, name)] + args, limit=limit, context=context)
        else:
            ids = self.search(cr, uid, args, limit=limit, context=context)
        result = self.name_get(cr, uid, ids, context=context)
        return result
    
    def name_get(self, cr, uid, ids, context=None):
        if not len(ids):
            return []
        res = []
        if context.get('also_get_code', True):
            for obj in self.browse(cr, uid, ids, context=context):
                name = ''
                if obj.code:
                    name += obj.code + ' - '
                if obj.name:
                    name += obj.name
                res.append((obj.id, name))
        else: res = super(aas_user, self).name_get(cr, uid, ids, context=context)
        return res
    
    def fields_view_get(self, cr, uid, view_id=False, view_type='form', context=None, toolbar=False, submenu=False):
        if view_type == 'form':
            if not context: context = {}
            type = context.get('type', '')
            if type:
                view_xml_id = 'aas_user_form_view'
                year_obj = self.pool.get('aas.academic.year')
                view_id = year_obj.get_view_id(cr, uid, 'aas_user', view_xml_id)
        result = super(aas_user, self).fields_view_get(cr, uid, view_id, view_type, context=context, toolbar=toolbar, submenu=submenu)
        return result
    
    def get_study_result(self, cr, uid, student_id, year_id=False, semester_id=False, mode='full', context=None):
        res = {'details': {}, 'total_credit': 0, 'gpa': 0.00}
        course_obj = self.pool.get('aas.course.course')
        course_student_obj = self.pool.get('aas.course.student')
        list_obj = self.pool.get('aas.course.list')
        
        if student_id:
            args = [('course_id.state', 'in', ('closed',)), ('student_id', '=', student_id)]
            if year_id:
                args.append(('course_id.academic_year', '=', year_id))
            if semester_id:
                args.append(('course_id.academic_semester', '=', semester_id))
            
            computed = 0.00
            
            current_dict = {}
            
            course_student_ids = course_student_obj.search(cr, uid, args, context=context)
            logging.info('----------course_student_ids = %s',course_student_ids)
            for cs in course_student_obj.browse(cr, uid, course_student_ids, context=context):
                year_name = cs.course_id.academic_year.name
                semester_name = cs.course_id.academic_semester.name
                if not res['details'].has_key(year_name):
                    res['details'].update({year_name: {}})
                if not res['details'][year_name].has_key(semester_name):
                    res['details'][year_name].update({semester_name: []})
                
                do_append = True
                if mode != 'full':
                    if current_dict.has_key(cs.course_id.subject_id.code):
                        current_max_mark = current_dict[cs.course_id.subject_id.code][2]
                        if cs.avg_mark >= current_max_mark:
                            current_max_year = current_dict[cs.course_id.subject_id.code][0]
                            current_max_semester = current_dict[cs.course_id.subject_id.code][1]
                            del res[stu_id]['details'][current_max_year][current_max_semester]
                        else:
                            do_append = False
                if do_append:
                    do_update_dict = True
                    if cs.does_pass:
                        max_mark = cs.avg_mark
                        max_credit = cs.course_id.total_credit
                        if current_dict.has_key(cs.course_id.subject_id.code):
                            if max_mark >= current_dict[cs.course_id.subject_id.code][2]:
                                current_dict[cs.course_id.subject_id.code][2] = max_mark
                                current_dict[cs.course_id.subject_id.code][3] = max_credit
                            else:
                                max_mark = current_dict[cs.course_id.subject_id.code][2]
                                max_mark = current_dict[cs.course_id.subject_id.code][3]
                            do_update_dict = False
                    
                    if do_update_dict:
                        current_dict[cs.course_id.subject_id.code] = [year_name, semester_name, cs.avg_mark, cs.course_id.total_credit]
                    
                    res['details'][year_name][semester_name].append([year_name,
                                                      semester_name,
                                                      cs.course_id.subject_id.code,
                                                      cs.course_id.subject_id.name,
                                                      cs.course_id.th_credit,
                                                      cs.course_id.pr_credit,
                                                      cs.course_id.total_credit,
                                                      cs.avg_mark,
                                                      cs.note,
                                                      cs.does_pass])
            for key in current_dict.keys():
                res['total_credit'] += current_dict[key][3]
                computed += current_dict[key][2] * current_dict[key][3]
            if res['total_credit'] > 0:
                res['gpa'] = round(computed / float(res['total_credit']), 2)
        return res
    
    
    def get_study_result_many(self, cr, uid, students_ids, year_id=False, semester_id=False, mode='full', context=None):
        res = {}
        for id in students_ids:
            res.update({id: {'details': {}, 'total_credit': 0, 'gpa': 0.00}})
        course_obj = self.pool.get('aas.course.course')
        course_student_obj = self.pool.get('aas.course.student')
        list_obj = self.pool.get('aas.course.list')
        
        if students_ids:
            args = [('course_id.state', 'in', ('closed',)), ('student_id', 'in', students_ids)]
            if year_id:
                args.append(('course_id.academic_year', '=', year_id))
            if semester_id:
                args.append(('course_id.academic_semester', '=', semester_id))
            
            computed = 0.00
            
            current_dict = {}
            course_student_ids = course_student_obj.search(cr, uid, args, context=context)
            for cs in course_student_obj.browse(cr, uid, course_student_ids, context=context):
                stu_id = cs.student_id.id
                year_name = cs.course_id.academic_year.name
                semester_name = cs.course_id.academic_semester.name
                if not res[stu_id]['details'].has_key(year_name):
                    res[stu_id]['details'].update({year_name: {}})
                if not res[stu_id]['details'][year_name].has_key(semester_name):
                    res[stu_id]['details'][year_name].update({semester_name: []})
                
                do_append = True
                if mode != 'full':
                    if current_dict.has_key(cs.course_id.subject_id.code):
                        current_max_mark = current_dict[cs.course_id.subject_id.code][2]
                        if cs.avg_mark >= current_max_mark:
                            current_max_year = current_dict[cs.course_id.subject_id.code][0]
                            current_max_semester = current_dict[cs.course_id.subject_id.code][1]
                            del res[stu_id]['details'][current_max_year][current_max_semester]
                            current_dict[cs.course_id.subject_id.code] = [year_name, semester_name,cs.avg_mark]
                        else:
                            do_append = False
                
                if do_append:  
                    res[stu_id]['details'][year_name][semester_name].append([year_name,
                                                  semester_name,
                                                  cs.course_id.subject_id.code,
                                                  cs.course_id.subject_id.name,
                                                  cs.course_id.th_credit,
                                                  cs.course_id.pr_credit,
                                                  cs.course_id.total_credit,
                                                  cs.avg_mark,
                                                  cs.note,
                                                  cs.does_pass])
                    if cs.does_pass:
                        res[stu_id]['total_credit'] += cs.course_id.total_credit
                        computed += cs.course_id.total_credit * cs.avg_mark
            
            if res[stu_id]['total_credit'] > 0:
                res[stu_id]['gpa'] = round(computed / float(res[stu_id]['total_credit']), 2)
            print current_dict
        return res
    
    def get_frame_result(self, cr, uid, student_id, context=None):
        res = {'details': [], 'total_credit_gained': 0, 'total_credit_required': 0, 'finished': False, 'percentage': '0.0%'}
        course_obj = self.pool.get('aas.course.course')
        course_student_obj = self.pool.get('aas.course.student')
        list_obj = self.pool.get('aas.course.list')
        user_obj = self.pool.get('res.users')
        
        if student_id:
            student = user_obj.browse(cr, uid, student_id, context=context)
            if student.frame_id.id:
                res.update({'total_credit_required': student.frame_id.number_of_credits}) 
                total_credit_gained = 0
                for detail in student.frame_id.details:
                    semester = detail.semester
                    subject_code = detail.subject_code
                    subject_name = detail.subject_id.name
                    type = detail.type.name
                    total_credit = detail.total_credit
                    total_credit_course = 0
                    list_of_subjects = [detail.subject_id.id]
                    course_code = ''
                    mark = ''
                    eqvl = ''
                    
                    if detail.subject_id.eqvl_subjects:
                        for s in detail.subject_id.eqvl_subjects:
                            list_of_subjects.append(s.id)
                    args = [('course_id.state', 'in', ('closed',)), 
                            ('student_id', '=', student_id), 
                            ('does_pass', '=', True),
                            ('course_id.subject_id', 'in', list_of_subjects)]
                    marks_subject_ids = []
                    course_student_ids = course_student_obj.search(cr, uid, args, context=context)
                    for cs in course_student_obj.browse(cr, uid, course_student_ids, context=context):
                        marks_subject_ids.append([cs.avg_mark, cs.course_id.subject_id.id, cs.course_id.subject_id.code + ' - ' + cs.course_id.subject_id.name, 
                                                  cs.course_id.name, cs.course_id.total_credit])
                    if marks_subject_ids:
                        index = 0
                        i = -1
                        max_mark = 0
                        for _mark, s_id, _eqvl, c_id, c_credit in marks_subject_ids:
                            i += 1
                            if _mark > max_mark:
                                index = i
                                max_mark = _mark
                                course_code = c_id
                                total_credit_course = c_credit
                        mark = str(max_mark)
                        (_mark, s_id, _eqvl, c_id, c_credit) = marks_subject_ids[index]
                        total_credit_gained += c_credit
                        if s_id != detail.subject_id.id:
                            eqvl = _eqvl
            
                    res['details'].append([semester, subject_code, subject_name, type, total_credit, course_code, mark, eqvl, total_credit_course])
                res.update({'total_credit_gained': total_credit_gained}) 
        if res['total_credit_gained'] >= res['total_credit_required']:
            res.update({'finished': True})
        if res['total_credit_required'] > 0:
            percentage = round((float(res['total_credit_gained']) * 100.0 / (res['total_credit_required'])), 1)
            res.update({'percentage': str(percentage) + '%'}) 
        return res
    
    def determine_access(self, cr, uid, args):
        if uid == 1: return True
        res = True
        if not args: args = {}
        model = args.get('model', False)
        if model:
#            print args
            access = self.get_access_rights(cr, uid, model)
#            print access
            what_need_to_check = args.get('check', [])
            for temp in what_need_to_check:
                if access[temp] == False:
                    res = False
                    break
        return res
aas_user()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
